package com.apes.fn.scm.retailOrder.service;

import com.alibaba.fastjson.JSONObject;
import com.apes.crm.business.model.InsuranceCompany;
import com.apes.fn.scm.contract.FnContract;
import com.apes.fn.scm.contract.FnContractRepository;
import com.apes.fn.scm.insuranceRules.InsuranceRule;
import com.apes.fn.scm.insuranceRules.InsuranceRuleService;
import com.apes.fn.scm.retailOrder.model.RetailOrder;
import com.apes.fn.scm.retailOrder.repository.RetailOrderRepository;
import com.apes.fn.scm.retailOrder.service.expense.AbstractRetailOrderFnExpense;
import com.apes.fn.scm.retailOrder.service.expense.FnBase2FnBase;
import com.apes.fn.scm.retailOrder.service.expense.FnStore2FnBase;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.*;

/**
 * 生成费用单
 *
 * @author wuq
 * @create 2020-04-10 14:08
 */
@Service
public class RetailOrderFnExpenseOrderService extends DomainService {

    /**
     * 场景流使用
     * @param simpleRequest retailOrder
     * @return RetailOrder
     */
    public RetailOrder create(SimpleRequest simpleRequest) {
        RetailOrder retailOrder = simpleRequest.getO(RetailOrder.class);
        return process(retailOrder);
    }

    /**
     * esb 调用
     * @param request retailOrderId
     * @return RetailOrder
     */
    public RetailOrder createExpense(SimpleRequest request){
        String id = request.get("id");
        RetailOrder retailOrder = SpringManager.getBean(RetailOrderRepository.class).findOne(id);
        return process(retailOrder);
    }

    @Autowired
    private EntityManager entityManager;
    public void test(SimpleRequest request) {
        entityManager.createNativeQuery("SELECT SOURCE FROM FN_SETTLE_EXPENSE_TEST")
                .unwrap(NativeQueryImpl.class)
                .setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP)
                .getResultStream()
                .forEach(m -> {
                    String id = (String) ((Map) m).get("SOURCE");
                    RetailOrder retailOrder = SpringManager.getBean(RetailOrderRepository.class).findOne(id);
                    process(retailOrder);
                });
    }

    private RetailOrder process(RetailOrder retailOrder) {
        // 获取策略
        PartyRole platformCompany = getPlatFormCompany(retailOrder.getGetCarDept().getCompany());       // 获取平台公司
        JSONObject condition = getConditionRule(retailOrder.getServiceDept(),retailOrder.getInsuranceCompany(),retailOrder.getCompany());   // 获取条件策略规则
        if (condition.isEmpty()) throw new RuntimeException("未定义赋能平台费用条件策略");

      AbstractRetailOrderFnExpense retailOrderFnExpense = null;

        // 直营自定损、赋能自定损、直营子公司自定损
        if ( retailOrder.getGetCarDept().getId().equals(retailOrder.getServiceDept().getId()) ) {
            retailOrderFnExpense = new FnBase2FnBase(platformCompany, retailOrder);
        } else {
            /* 跨公司部分
             * 直营：直营转直营基地、直营转赋能基地、直营转直营子公司
             * 直营子公司：直营子公司转赋能基地、直营子公司转直营基地
             * 赋能：赋能店转赋能基地、赋能店转直营子公司、赋能转直营基地
             */
            retailOrderFnExpense = new FnStore2FnBase(platformCompany, retailOrder);
        }

        retailOrderFnExpense.create(condition);
        return retailOrder;
    }

    /**
     * 根据赋能门店查询合同对应的公司
     *
     * @param partyRole partyRole
     * @return PartyRole
     */
    private PartyRole getPlatFormCompany(PartyRole partyRole) {
        ArrayList rows = new ArrayList();
        rows.add(MapUtil.mapper("field", "state", "operator", "EQ", "value", "approve"));
        rows.add(MapUtil.mapper("field", "validPeriod", "operator", "GT", "value", new Date()));
        rows.add(MapUtil.mapper("field", "partner.id", "operator", "EQ", "value", partyRole.getId()));
        FnContract contract = SpringManager.getBean(FnContractRepository.class).findAll(JpaDsl.toCriteria(rows)).stream().findFirst().orElse(null);
        if (contract == null) {
            // 2022-01-15 按照老胡要求，取不到值的情况下，就默认 1007，后期业务出现错误数据，调整不管
            return SpringManager.getBean(PartyRoleRepository.class).findOne("1007");
        }
        return contract.getCompany();
    }

    /**
     * 获取定损业务费率
     * @return {"A005":0,"A006":0,"A003":0,"A004":0,"A001":0,"A002":0}
     * A001	代码单定损费率
     * A002	非代码单定损费率
     * A003	推修定损费率
     * A004	代码单信息费率
     * A005	非代码单信息费率
     * A006	推修信息费率
     */
    public JSONObject getConditionRule(Dept serviceDept,InsuranceCompany insuranceCompany, PartyRole storeCompany) {
        // 查找对应的车宝公司
        InsuranceRule insuranceRule = SpringManager.getBean(InsuranceRuleService.class)
                .findByDeptAndInsuranceCompany(serviceDept, insuranceCompany);
        if (Objects.isNull(insuranceRule)&&insuranceCompany.isCooperation()){
            throw new RuntimeException("没有找到车险规则，公司编码："+ serviceDept.getCompany().getId() + "，保险公司编码："+ insuranceCompany.getId());
        }
        // 获取基地公司的运营模式  001071 合伙人  001072  直营   001073  赋能店
        String operation = serviceDept.getCompany().getParty().getCorporate().getOperation().getId();

        // OPERATION,KGSNX,COMPANY_ID
        Map<String, Object> map = new HashMap<>();
        map.put("conditionStrategyId", "XS52");
        // 运营模式
        map.put("OPERATION", operation);
        // 下游公司
        map.put("COMPANY_ID", storeCompany.getId());
        map.put("KGSNX", storeCompany.getId().equals(serviceDept.getCompany().getId()) ? 0 : 1);
        map.put("SYS_RQ", new Date());

        Object obj = invoke("condition.execConditionStrategy", map);
        JSONObject returnData = new JSONObject(MapUtil.mapped(obj));
        // A001,A002,A003,A004,A005,A006

        if (!returnData.containsKey("A001")) {
            throw new RuntimeException("没有定义对应的条件策略,请先定义定损业务费率");
        }
        return returnData;
    }

    /**
     * 获取平台服务费
     * 根据公司的运营模式、公司编码查询平台服务费
     *
     * @param company 公司
     * @return 平台服务费率
     */
    public double getPlatformFreeRatio(PartyRole company) {
        Map map = MapUtil.mapper(
                "OPERATION", company.getParty().getCorporate().getOperation().getId(), "COMPANY_ID", company.getId(), "SYS_RQ", new Date(), "conditionStrategyId", "FW_PT_SK"
        );
        Object obj = invoke("condition.execConditionStrategy", map);
        JSONObject result = new JSONObject(MapUtil.mapped(obj));
        return result.getDoubleValue("T001");
    }

    public Map getStoreQuota(String deptId) {
        Map<String, Object> result = new HashMap<>();
        String sql = "SELECT A.MDID, A.MDMC, A.DTCXJE, A.ZCXJE, A.HSDSED, A.EWDSED, A.ZDSED, A.SDSED, A.SYDSED, A.DTGQED FROM SER_STORE_QUOTA A WHERE MDID = :MDID ";
        Query query = entityManager.createNativeQuery(sql);
        query.setParameter("MDID", deptId);
        query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        List<Map> resultList = query.getResultList();
        if ( resultList.size() > 1) throw new RuntimeException("根据门店找到多条定损额度，请检查！");
        if ( resultList.size() == 1 ) return resultList.get(0);
        return result;
    }
}
